/*
 * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
 *
 * Copyright (C) 2020 Tencent.  All rights reserved.
 *
 * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
 *
 * A copy of the MIT License is included in this file.
 *
 *
 * Terms of the MIT License:
 * ---------------------------------------------------
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.tencent.bkrepo.common.artifact.permission

import com.tencent.bkrepo.auth.pojo.enums.ResourceType
import com.tencent.bkrepo.common.artifact.constant.PROJECT_ID
import com.tencent.bkrepo.common.artifact.repository.context.ArtifactContextHolder
import com.tencent.bkrepo.common.metadata.permission.PermissionManager
import com.tencent.bkrepo.common.security.exception.PermissionException
import com.tencent.bkrepo.common.security.permission.Permission
import com.tencent.bkrepo.common.security.permission.PermissionCheckHandler
import com.tencent.bkrepo.common.security.permission.Principal
import com.tencent.bkrepo.common.service.util.HttpContextHolder
import org.springframework.web.servlet.HandlerMapping

class ArtifactPermissionCheckHandler(
    private val permissionManager: PermissionManager
) : PermissionCheckHandler {
    override fun onPermissionCheck(userId: String, permission: Permission) {
        when (permission.type) {
            ResourceType.PROJECT -> {
                val uriAttribute = HttpContextHolder
                    .getRequest()
                    .getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE)
                require(uriAttribute is Map<*, *>)
                val projectId = uriAttribute[PROJECT_ID]?.toString() ?: throw PermissionException()
                permissionManager.checkProjectPermission(permission.action, projectId)
            }
            ResourceType.REPO -> {
                with(ArtifactContextHolder.getRepoDetail()!!) {
                    permissionManager.checkRepoPermission(
                        action = permission.action,
                        projectId = projectId,
                        repoName = name,
                        public = public,
                        anonymous = permission.anonymous
                    )
                }
            }
            ResourceType.NODE -> {
                val path = ArtifactContextHolder.getArtifactInfo()!!.getArtifactFullPath()
                with(ArtifactContextHolder.getRepoDetail()!!) {
                    permissionManager.checkNodePermission(
                        permission.action,
                        projectId,
                        name,
                        path,
                        public = public,
                        anonymous = permission.anonymous
                    )
                }
            }
            else -> throw PermissionException("unsupported resource type")
        }
    }

    override fun onPrincipalCheck(userId: String, principal: Principal) {
        permissionManager.checkPrincipal(userId, principal.type)
    }
}
